package com.frostmourne.mxsguimaker.objects;

import com.gitee.mxstarsex.objects.builders.bukkit.inventory.InventoryBuilder;
import com.gitee.mxstarsex.objects.builders.bukkit.item.ItemBuilder;
import com.gitee.mxstarsex.utils.MathUtils;
import com.gitee.mxstarsex.utils.StringUtils;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GuiMakerMold {

    public static final Map<String,GuiMakerMold> GUI_MAKER_MOLD_MAP = new HashMap<>();
    public static GuiMakerMold getGuiMakerMold(String name){
        return GUI_MAKER_MOLD_MAP.getOrDefault(name,null);
    }

    public static GuiMakerMold getGuiMakerMold(Inventory inventory){
        if (inventory != null && inventory.getHolder() != null &&
        inventory.getHolder() instanceof GuiMakerHolder){

            GuiMakerHolder holder = (GuiMakerHolder) inventory.getHolder();
            String name = holder.getId();
            return GUI_MAKER_MOLD_MAP.getOrDefault(name,null);

        }
        return null;
    }

    private final File file;
    private final FileConfiguration config;
    private final InventoryBuilder inventoryBuilder;
    private final String name;
    private final GuiMakerHolder holder;
    private final Map<String,String> scripts = new HashMap<>();

    public final Map<String,String> places = new HashMap<>();
    private boolean saveItems;
    private boolean clickSelf;

    public Map<String, String> getScripts() {
        return scripts;
    }
    public String getScript(String name){
        return scripts.getOrDefault(name,null);
    }

    public Map<String, String> getPlaces() {
        return places;
    }

    public GuiMakerMold(File file) {
        this.file = file;
        this.name = this.file.getName().replace(".yml","");
        this.holder = new GuiMakerHolder(name);
        this.config = YamlConfiguration.loadConfiguration(file);
        this.inventoryBuilder = new InventoryBuilder(file,holder);
        if (this.config.getKeys(false).contains("Scripts")){

            for (String s : this.config.getConfigurationSection("Scripts").getKeys(false)){

                String script = this.config.getString("Scripts." + s);
                if (s.equalsIgnoreCase("click")){

                    for (String icon : this.config.getConfigurationSection("Scripts." + s).getKeys(false)){
                        script = this.config.getString("Scripts." + s + "." + icon);
                        scripts.put("click-" + icon.toLowerCase(),script);
                    }

                }else{
                    this.scripts.put(s.toLowerCase(),script);
                }

            }

        }
        if (this.config.getKeys(false).contains("Places")){

            for (String key : this.config.getConfigurationSection("Places").getKeys(false)){

                String value = this.config.getString("Places." + key);

                this.places.put(key,value);

            }

        }
        this.saveItems = this.config.getBoolean("Inventory.Save-Item");
        this.clickSelf = getConfig().getBoolean("Inventory.Click-Self");
    }

    public void setClickSelf(boolean clickSelf) {
        this.clickSelf = clickSelf;
    }

    public boolean isClickSelf() {
        return clickSelf;
    }

    public boolean isSaveItems() {
        return saveItems;
    }

    public void setSaveItems(boolean saveItems) {
        this.saveItems = saveItems;
    }

    public void invokeIconScripts(String icon, String funcName, Map<String,Object> objectMap, Object... args){


        String script = scripts.getOrDefault(icon,null);
        if (script != null){

            JSEngine jsEngine = new JSEngine();
            for (String s : objectMap.keySet()){
                jsEngine = jsEngine.putVariable(s,objectMap.get(s));
            }

            if (args.length == 0){
                jsEngine.invoke(script,funcName);
            }else{

                for (Object obj : args){
                    if (obj instanceof Player){
                        jsEngine.putVariable("places",initVariables((Player) obj));
                    }
                }

                jsEngine.invoke(script,funcName,args);
            }

        }

    }

    public Map<String,String> initVariables(Player player){
        Map<String,String> places = new HashMap<>();

        for (String s : this.places.keySet()){

            String value = this.places.get(s);
            value = PlaceholderAPI.setPlaceholders(player,value);

            while (value.contains("{") && value.contains("}")){

                String sub = StringUtils.subString(value,"{","}");
                Object o = MathUtils.runJavaScript(sub);

                value = value.replace("{" + sub + "}",String.valueOf(o));

            }

            value = ChatColor.translateAlternateColorCodes('&',value);

            places.put(s,value);
        }
        return places;
    }

    public void open(Player player){

        InventoryBuilder builder = new InventoryBuilder(inventoryBuilder);
        PlayerData data = PlayerData.getPlayerData(player);
        Map<Integer, ItemStack> itemMap = data.getItemMap(name);
        Map<String,String> places = initVariables(player);


        for (int i : itemMap.keySet()){
            builder.setItem(i,itemMap.get(i));
        }

        Inventory inventory = builder.buildView().buildView(player, 1, false);

        for (int i = 0; i < inventory.getSize(); i++) {


            ItemStack itemStack = inventory.getItem(i);

            if (itemStack == null){
                continue;
            }

            ItemBuilder itemBuilder = new ItemBuilder(new ItemStack(itemStack));
            for (String s : places.keySet()){
                itemBuilder.replaceLore("$" + s,places.get(s));
            }

            itemStack = itemBuilder.build();

            inventory.setItem(i,itemStack);
        }

        player.openInventory(inventory);

    }
    public void open(Player target,Player looker){

        InventoryBuilder builder = new InventoryBuilder(inventoryBuilder);
        PlayerData data = PlayerData.getPlayerData(target);
        Map<Integer, ItemStack> itemMap = data.getItemMap(name);
        Map<String,String> places = initVariables(target);


        Inventory inventory = builder.buildView().buildView(target, 1, false);

        for (int i = 0; i < 54; i++) {


            ItemStack itemStack = inventory.getItem(i);

            ItemBuilder itemBuilder = new ItemBuilder(new ItemStack(itemStack));
            for (String s : places.keySet()){
                itemBuilder.replaceLore("$" + s,places.get(s));
            }

            itemStack = itemBuilder.build();

            inventory.setItem(i,itemStack);
        }

        target.openInventory(inventory);

        looker.openInventory(builder.buildView().buildView(target,1,false));

    }

    public File getFile() {
        return file;
    }

    public FileConfiguration getConfig() {
        return config;
    }

    public InventoryBuilder getInventoryBuilder() {
        return inventoryBuilder;
    }

    public String getName() {
        return name;
    }

    public GuiMakerHolder getHolder() {
        return holder;
    }
}
